import axios from "axios";

const queryTYBlockStr = `
query blocks {
    t$td_start: blocks(
        first: 1
        orderBy: timestamp
        orderDirection: desc
        where: {timestamp_gt: $td_start, timestamp_lt: $td_end}
    ) {
        number
        __typename
    }
    t$yd_start: blocks(
        first: 1
        orderBy: timestamp
        orderDirection: desc
        where: {timestamp_gt: $yd_start, timestamp_lt: $yd_end}
    ) {
        number
        __typename
    }
}
`;

const queryBlockStr = `
query blocks {
    t$td_start: blocks(
        first: 1
        orderBy: timestamp
        orderDirection: desc
        where: {timestamp_gt: $td_start, timestamp_lt: $td_end}
    ) {
        number
        __typename
    }
}
`;

const query2Symbols = `
query blocks {
    t170erer4000: token(id: "0x0001a500a6b18995b03f44bb040a5ffc28e45cb0", block: {number: 18637909}) {
        derivedETH
        tradeVolume
        tradeVolumeUSD
        __typename
    }
    t170sd34400: token(id: "0x0001a500a6b18995b03f44bb040a5ffc28e45cb0", block: {number: 18637909}) {
        derivedETH
        tradeVolume
        tradeVolumeUSD
        __typename
    }
    t1700dfdf200: token(id: "0x0001a500a6b18995b03f44bb040a5ffc28e45cb0", block: {number: 18637909}) {
        derivedETH
        tradeVolume
        tradeVolumeUSD
        __typename
    }
    p1700dfdf200: bundles(block: {number: 18581247}) {
        ethPrice
    }
}
`;

const query3Symbols = `
query MyQuery {

    t:bundles(block: {number: 18581247}) {
      ethPriceUSD
    }
    y:bundles(block: {number: 18581246}) {
      ethPriceUSD
    }
    ts: tokens(block: {number: 18581247}, where: {id_in: ["0x514910771af9ca656af840dff83e8264ecf986ca","0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"]})
    {
      symbol
      derivedETH
      id
    }
    ys: tokens(block: {number: 18581246}, where: {id_in: ["0x514910771af9ca656af840dff83e8264ecf986ca","0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"]})
    {
      symbol
      derivedETH
      id
    }
  }
`;

// ts: tokens(block: {number: ${time1}}, where: {id_in: [${ids}]})
function getBlockQueryV3(list: any[], time1 = 0, time2 = 0) {
    let ids = list.map(i => `"${i}"`).join(",");
    // console.warn("ids", ids)
    let ary = [];
    ary.push("query MyQuery {");
    ary.push(`
    ts: tokens(where: {id_in: [${ids}]})
    {
      symbol
      derivedETH
      id
    }
    `);
    // ary.push(`
    // ys: tokens(block: {number: ${time2}}, where: {id_in: [${ids}]})
    // {
    //   symbol
    //   derivedETH
    //   id
    // }
    // `);
    ary.push(`t: bundle(id: "1") {
        ethPriceUSD
    }`);

    // time2 &&
    //     ary.push(`y: bundles(block: {number: ${time2}}) {
    //     ethPriceUSD
    // }`);
    ary.push("}");
    return ary.join("");
}

// ts: tokens(block: {number: ${time1}}, where: {id_in: [${ids}]})
function getBlockQueryV32(list: any[], time1: number, time2?: number) {
    let ids = list.map(i => `"${i}"`).join(",");
    // console.warn("ids", ids)
    let ary = [];
    ary.push("query MyQuery {");
    ary.push(`
    ts: tokens(where: {id_in: [${ids}]})
    {
      symbol
      derivedETH
      id
    }
    `);
    // ary.push(`
    // ys: tokens(block: {number: ${time2}}, where: {id_in: [${ids}]})
    // {
    //   symbol
    //   derivedETH
    //   id
    // }
    // `);
    ary.push(`t: bundle(id: "1") {
        ethPrice
    }`);

    // time2 &&
    //     ary.push(`y: bundles(block: {number: ${time2}}) {
    //     ethPrice
    // }`);
    ary.push("}");
    return ary.join("");
}

function getBlockQuery(list: any[], time1: number, time2?: number) {
    let ary = [];
    ary.push("query blocks {");
    for (var i = 0; i < list.length; i++) {
        ary.push(`
        t_${list[i]}: token(id: "${list[i]}", block: {number: ${time1}}) {
            derivedETH
            tradeVolume
            tradeVolumeUSD
            __typename
        }
        `);

        // time2 &&
        //     ary.push(`
        // y_${list[i]}: token(id: "${list[i]}", block: {number: ${time2}}) {
        //     derivedETH
        //     tradeVolume
        //     tradeVolumeUSD
        //     __typename
        // }
        // `);
    }
    ary.push(`t: bundles(block: {number: ${time1}}) {
        ethPrice
    }`);

    // time2 &&
    //     ary.push(`y: bundles(block: {number: ${time2}}) {
    //     ethPrice
    // }`);
    ary.push("}");
    return ary.join("");
}

function getTodayYesterdayParam(timer?: number) {
    timer = timer || Date.now();
    let str = queryTYBlockStr.trim();
    let td = Math.floor(timer / 1000);
    let yd = Math.floor(timer / 1000) - 24 * 60 * 60;

    let td_start = td - 60 * 10;
    // let td_start = td;
    let td_end = td;
    let yd_start = yd - 60 * 10;
    // let yd_start = yd;
    let yd_end = yd;

    str = str.replaceAll("$td_start", td_start + "");
    str = str.replaceAll("$td_end", td_end + "");
    str = str.replaceAll("$yd_start", yd_start + "");
    str = str.replaceAll("$yd_end", yd_end + "");

    return {
        today: td_start,
        yesterday: yd_start,
        param: {
            operationName: "blocks",
            variables: {},
            query: str
        }
    };
}

function getBlockParamByTime(timer?: number) {
    timer = timer || Date.now();
    let str = queryBlockStr.trim();
    let td = Math.floor(timer / 1000);
    let td_start = td - 60 * 10;
    // let td_start = td;
    let td_end = td;

    str = str.replaceAll("$td_start", td_start + "");
    str = str.replaceAll("$td_end", td_end + "");
    return {
        key: "t" + td_start,
        param: {
            operationName: "blocks",
            variables: {},
            query: str
        }
    };
}

export async function getPriceByTime(tokens: string[], timer?: number) {
    return new Promise(async resolve => {
        let bnumber: any = await new Promise(resolve => {
            const obj = getBlockParamByTime(timer);
            // console.log(obj);
            let url = "https://api.thegraph.com/subgraphs/name/blocklytics/ethereum-blocks";

            axios
                .post(url, obj.param)
                .then(res => {
                    // console.error("res----------------bd----------", res.data);
                    let temp = res.data.data;
                    if (temp) {
                        resolve(temp[obj.key][0].number);
                    } else {
                        resolve(null);
                    }
                })
                .catch(e => {
                    // console.error("err-----------", e);
                    resolve(null);
                });
        });

        // console.warn(bnumber);

        let qs = getBlockQuery(tokens, bnumber);

        let url = "https://api.thegraph.com/subgraphs/name/ianlapham/uniswap-v2-dev";
        let param = {
            variables: {},
            operationName: "blocks",
            query: qs
        };
        let map: any = {};
        axios
            .post(url, param)
            .then(res => {
                // console.error("res-----------over----------", res.data);
                let obj = res.data?.data;
                if (obj) {
                    let ethPrice = obj.t[0].ethPrice;
                    // console.log("ethPrice", ethPrice);
                    ethPrice = Number(ethPrice);
                    tokens.forEach(i => {
                        // console.log(i, "derivedETH");
                        console.log(obj["t_" + i].derivedETH);
                        map[i] = ethPrice * Number(obj["t_" + i].derivedETH);
                    });
                    // console.log("价格", map);
                }
            })
            .catch(e => {
                // console.log(e);
            })
            .finally(() => {
                resolve(map);
            });
    });
}

export async function getTodayYesterdayPrice(v2: boolean, tokens: string[], timer?: number, tNumber?: number, yNumber?: number) {
    return new Promise(async resolve => {
        let map: any = {};
        // let qs;
        // if (tNumber && yNumber) {

        // } else {
        //     let res: any = await getTodayYesterdayBlocks(timer);
        //     tNumber = res.today;
        //     yNumber = res.yesterday;
        // }

        let param = {
            variables: {},
            operationName: "",
            query: ""
        };

        let url;
        if (v2) {
            url = "https://api.thegraph.com/subgraphs/name/ianlapham/uniswap-v2-dev";
            // param.operationName = "blocks";
            // param.query = getBlockQuery(tokens, tNumber!, yNumber);
            param.operationName = "MyQuery";
            param.query = getBlockQueryV32(tokens, tNumber!, yNumber);
        } else {
            url = "https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3";
            param.operationName = "MyQuery";
            param.query = getBlockQueryV3(tokens, tNumber!, yNumber);
        }

        axios
            .post(url, param)
            .then(res => {
                let obj = res.data?.data;
                if (obj) {
                    if (v2) {
                        // console.error("res---------v2---------all------", res.data);
                        let ethPriceT = obj.t.ethPrice;
                        ethPriceT = Number(ethPriceT);
                        // let ethPriceY = obj.t[0].ethPrice;
                        // ethPriceY = Number(ethPriceY);

                        tokens.forEach(i => {
                            map[i] = {};
                            obj.ts.forEach((item: any) => {
                                if (item.id == i) {
                                    map[i].t = ethPriceT * Number(item.derivedETH);
                                }
                            });
                            // obj.ys.forEach((item: any) => {
                            //     if (item.id == i) {
                            //         map[i].y = ethPriceY * Number(item.derivedETH);
                            //     }
                            // });
                        });
                        // map["0x"] = { t: ethPriceT, y: ethPriceY };
                        map["0x"] = { t: ethPriceT };
                    } else {
                        let ethPriceT = Number(obj.t.ethPriceUSD);
                        // let ethPriceY = Number(obj.y[0].ethPriceUSD);
                        tokens.forEach(i => {
                            map[i] = {};
                            let to = obj.ts.find((t: any) => t.id == i);
                            if (to) {
                                map[i].t = Number(to.derivedETH) * ethPriceT;
                            }
                            // let yo = obj.ys.find((t: any) => t.id == i);
                            // if (yo) {
                            //     map[i].y = Number(yo.derivedETH) * ethPriceY;
                            // }
                        });
                        // map["0x"] = { t: ethPriceT, y: ethPriceY };
                        map["0x"] = { t: ethPriceT };
                    }
                }
            })
            .catch(e => {
                // console.error("err-----------", e);
            })
            .finally(() => {
                resolve(map);
            });
    });
}

export function getTodayYesterdayBlocks(timer?: number) {
    return new Promise(resolve => {
        let url = "https://api.thegraph.com/subgraphs/name/blocklytics/ethereum-blocks";
        let obj = getTodayYesterdayParam(timer);
        axios
            .post(url, obj.param)
            .then(res => {
                let temp = res.data.data;
                if (temp) {
                    resolve({
                        today: temp["t" + obj.today][0].number,
                        yesterday: temp["t" + obj.yesterday][0].number
                    });
                } else {
                    resolve(null);
                }
            })
            .catch(e => {
                // console.error("err-----------", e);
                resolve(null);
            });
    });
}

// let url = "https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3?source=uniswap";
// let url = "https://api.thegraph.com/subgraphs/name/blocklytics/ethereum-blocks";
// let getBlocksParam = {
//     operationName: "blocks",
//     variables: {},
//     query: "query blocks {\n  t1701678360: blocks(\n    first: 1\n    orderBy: timestamp\n    orderDirection: desc\n    where: {timestamp_gt: 1701678360, timestamp_lt: 1701678960}\n  ) {\n    number\n    __typename\n  }\n  t1701591960: blocks(\n    first: 1\n    orderBy: timestamp\n    orderDirection: desc\n    where: {timestamp_gt: 1701591960, timestamp_lt: 1701592560}\n  ) {\n    number\n    __typename\n  }\n  t1701159960: blocks(\n    first: 1\n    orderBy: timestamp\n    orderDirection: desc\n    where: {timestamp_gt: 1701159960, timestamp_lt: 1701160560}\n  ) {\n    number\n    __typename\n  }\n}\n"
// };

// let getSymbolParam = {
//     operationName: "poolDayDatas",
//     variables: {
//         address: "0xc63b0708e2f7e69cb8a1df0e1389a98c35a76d52",
//         startTime: 1619170975,
//         skip: 0
//     },
//     query: "query poolDayDatas($startTime: Int!, $skip: Int!, $address: Bytes!) {\n  poolDayDatas(\n    first: 1000\n    skip: $skip\n    where: {pool: $address, date_gt: $startTime}\n    orderBy: date\n    orderDirection: asc\n    subgraphError: allow\n  ) {\n    date\n    volumeUSD\n    tvlUSD\n    feesUSD\n    pool {\n      feeTier\n      __typename\n    }\n    __typename\n  }\n}\n"
// };

// let p = getTodayYesterdayParam();
// console.log("pppppp", p);

// axios
//     .post(url, p)
//     .then(res => {
//         console.error("res-----------------------------", res.data);
//     })
//     .catch(e => {
//         console.error("err-----------", e);
//     });
